﻿using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using XCI.Core;
using XCI.Helper;
using XCI.Sys.Model;

namespace XCI.Sys.Service
{
    /// <summary>
    /// 账户服务
    /// </summary>
    public class SysAccountService
    {
        private const string RootUrl = "/api/sys/account";
        public static SysAccountService Instance { get; } = new SysAccountService();

        /// <summary>
        /// 用户登录
        /// </summary>
        /// <param name="account">账号</param>
        /// <param name="password">密码</param>
        /// <param name="captcha">验证码</param>
        public Task<BoolResult<SysUser>> LoginAsync(string account, string password, string captcha)
        {
            return App.Client.PostAsBoolResultAsync<SysUser>(new WebApiPostOption
            {
                Url = $"{RootUrl}/login",
                Data = new { account, password, captcha, winFormClientInfo = App.GetWinFormClientInfo() },
                Encrypt = true
            });
        }

        /// <summary>
        /// 用户注销
        /// </summary>
        /// <param name="userId">用户主键</param>
        public async Task LogoutAsync(string userId)
        {
            try
            {
                await App.Client.PostAsync($"{RootUrl}/logout", new { userId });
            }
            catch
            {
                // ignored
            }
        }

        /// <summary>
        /// 重置密码
        /// </summary>
        /// <param name="ids">主键字符串</param>
        /// <param name="newPassword">新密码</param>
        /// <returns>成功返回true</returns>
        public async Task RevisePasswordAsync(string ids, string newPassword)
        {
            await App.Client.PostAsync(new WebApiPostOption
            {
                Url = $"{RootUrl}/revisePassword",
                Data = new { ids, newPassword },
                Encrypt = true
            });
        }

        /// <summary>
        /// 修改用户密码
        /// </summary>
        /// <param name="id">用户主键</param>
        /// <param name="currentPassword">当前密码</param>
        /// <param name="newPassword">新密码</param>
        /// <returns>成功返回true</returns>
        public async Task ModifyPasswordAsync(string id, string currentPassword, string newPassword)
        {
            await App.Client.PostAsync(new WebApiPostOption
            {
                Url = $"{RootUrl}/modifyPassword",
                Data = new { id, currentPassword, newPassword },
                Encrypt = true
            });
        }

        /// <summary>
        /// 检查账号登录是否需要验证码
        /// </summary>
        /// <param name="account">用户账号</param>
        public async Task<bool> RequireCaptchaAsync(string account)
        {
            return await App.Client.PostAsync<bool>($"{RootUrl}/requireCaptcha", new { account });
        }

        /// <summary>
        /// 生成验证码
        /// </summary>
        /// <param name="account">账号</param>
        /// <param name="width">宽度,默认160</param>
        /// <param name="height">高度,默认48</param>
        /// <param name="type">验证码类型,可用值:math,gif,chinese</param>
        public async Task<byte[]> CaptchaAsync(string account, int width = 160, int height = 48, string type = "math")
        {
            string tempFile = Path.GetTempFileName();
            await App.Client.DownloadAsync($"{RootUrl}/captcha", tempFile, new { account, width, height, type });
            return File.Exists(tempFile) ? IOHelper.ReadFile(tempFile) : null;
        }

        /// <summary>
        /// 移除锁定用户
        /// </summary>
        /// <param name="account">用户账号</param>
        public async Task RemoveLockUserAsync(string account)
        {
            await App.Client.PostAsync($"{RootUrl}/removeLockUser", new { account });
        }

        /// <summary>
        /// 查询锁定用户列表
        /// </summary>
        public async Task<List<SysLockUser>> GetLockUserListAsync(string key)
        {
            return await App.Client.PostAsync<List<SysLockUser>>($"{RootUrl}/getLockUserList", new { key });
        }

        /// <summary>
        /// 激活在线用户
        /// </summary>
        /// <param name="userId">用户主键</param>
        public async Task ActiveOnlineUserAsync(string userId)
        {
            try
            {
                await App.Client.PostAsBoolResultAsync($"{RootUrl}/activeOnlineUser", new { userId, winFormClientInfo = App.GetWinFormClientInfo() });
            }
            catch
            {
                // ignored
            }
        }

        /// <summary>
        /// 根据用户主键注销在线用户
        /// </summary>
        /// <param name="userId">用户主键</param>
        public async Task LogoffOnlineUserByUserIdAsync(string userId)
        {
            await App.Client.PostAsync($"{RootUrl}/logoffOnlineUserByUserId", new { userId });
        }

        /// <summary>
        /// 查询在线用户列表
        /// </summary>
        public async Task<List<SysOnlineUser>> GetOnlineUserListAsync(string key)
        {
            return await App.Client.PostAsync<List<SysOnlineUser>>($"{RootUrl}/getOnlineUserList", new { key});
        }


        /// <summary>
        /// 查询用户权限
        /// </summary>
        /// <param name="userId">用户主键</param>
        public async Task<SysUserPermission> SelectUserPermissionAsync(string userId)
        {
            return await App.Client.PostAsync<SysUserPermission>(new WebApiPostOption
            {
                Url = $"{RootUrl}/selectUserPermission",
                Data = new { userId },
                Encrypt = true
            });
        }

        /// <summary>
        /// 清除服务端缓存中的用户权限
        /// </summary>
        /// <param name="userId">用户主键</param>
        public async Task ClearUserPermissionCacheAsync(string userId)
        {
            await App.Client.PostAsync(new WebApiPostOption
            {
                Url = $"{RootUrl}/clearUserPermissionCache",
                Data = new { userId },
                Encrypt = true
            });
        }


        /// <summary>
        /// 根据角色主键查询关系用户对象列表
        /// </summary>
        public async Task<List<SysUser>> SelectRelationUserListAsync(string roleId)
        {
            return await App.Client.PostAsync<List<SysUser>>($"{RootUrl}/selectRelationUserList", new { roleId });
        }
    }
}